今天將會介紹 k8s Namespace
針對 Namespace 的作用, 還有何時該使用 Namespace 跟用法做說明
在 k8s 叢集可以允許一個實體叢集具有多個虛擬叢集
而這些虛擬叢集就是所謂的 Namespace
在 k8s 叢集使用 Namespace 來針對叢集資源做管理
基礎的 k8s 叢集系統會有預設的以下4個 Namespace
內部有一些 k8s 在使用系統程序
比如說 Kublet 還有 Control Plane 等等
內部存放一些可以被公開存取的資源
比如說 ConfigMap
用來存放一些結點相關的物件
可以用來偵測結點狀態, 讓 kubelet 對結點送 heartbeats 檢測
預設存放使用者建立的資源
使用要者要使用自定義的 Namespace
可以使用以下指令
kubectl create namespace $namespace_name
舉例來說: 建立名稱為 my-namespace 的 Namespace
kubectl create namespace my-namespace
或者使用設定檔 my-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: my-namespace
再使用下面指令建立:
kubectl create -f my-namespace
想像假設把所有資源都直接放在 default namespace
當系統變複雜, 所有資源都會散佈在一起, 不好分類檢視
所以比較好的方式是把每個資源根據用途做分類
並且切割出分類項目的 Namespaces, 再依據不同分類放置對應的 Namespace
多個團隊使用同一個 k8s cluster, 有可能在佈署資源時遇到佈署名稱衝突的問題
舉例來說: 恰巧兩個 team 都發佈一個叫作 logger-app 的 deployment
這時, 如果沒有用 Namespace 切分就會遇到同名稱的 deployment 相互干擾的問題
這時就可以用 Namespace 做資源隔離給每個 team 給不同 Namespace , 這樣就不用擔心會被其他 team 影響
如果根據佈署環境切分成 staging 與 production 兩個 Namespace
另外把 nginx, elastic 相關的分別放置在 Nginx-Ingress-Controller, Elastic-Stack 兩個 Namespace
這時兩個佈署環境就可以透過 Namespace 共享這些 Service
藍綠佈署是指同一個應用或是服務根據設定同時佈署兩種版本來做測試
而再兩種佈署裡, 底層用到的資源是相同的比如 Nginx-Ingress-Controller, Elastic-Stack
假設有2個團隊 team A, team B
可以利用 Namespace 限制
team A 只能在 Namespace team_A_space 發佈服務, 建立資源
team B 只能再 Namespace team_B_space 發佈服務, 建立資源
彼此不干預各自團隊的開發佈署
另外也可以限制每個 Namespace 最多擁有多少資源比如CPU, RAM 等等
如此可以避免某一個 team 過度占用共有資源
舉例來說:
假設有一個 Namespace Project_A 內部有一個 ConfigMap 設定關於存取 Namespace database 的 database_url
在另一個 Namespace Project_B 內部的服務就無法透過 Namespace Project_A 內部的 ConfigMap 來存取 Namespace database
必須要在 Namespace Project_B 內部建立一個 ConfigMap 設定關於存取 Namespace database 的 database_url
這樣 Namespace Project_B 的服務才能透過內部的 ConfigMap 拿到存取 Namespace database 的 database_url 來存取 DB
所以每個 Namespace 必須有自己的 ConfigMap, Secrets
注意的是 Service 可以跨 Namespace 來存取
而體現在設定檔就如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-configmap
data:
db_url: mysql-service.database
注意的是 上面 ConfigMap 的 db_url 組成是以下模式組成
${service_name}.${namespace_name}
這些元件在 k8s 叢集裡是全域的
無法用 Namespace 來隔離
比如: Volume, Node
可以透過以下指令列出無法使用 Namespace 隔離的所有元件
kubectl api-resources --namespaced=false
相對的, 也可以用以下指令列出所有可用 Namespace 隔離的元件
kubectl api-resources --namespaced=true
首先建立一個設定檔 mysql-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-configmap
data:
db_url: mysql-service.database
假設直接操作以下指令
kubectl apply -f mysql-configmap.yaml
會發現因為沒指定 Namespace 最後會直接放到 Default Namespace
而如果要把這個 ConfigMap 放到 my-namespace 下
有兩個方式
1 kubectl 指令
kubectl apply -f mysql-configmap.yaml --namespace=my-namespace
2 設定檔的方式
更新 mysql-configmap.yaml 如下
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-configmap
namespace: my-namespace
data:
db_url: mysql-service.database
在 metadata的部份指定 namespace
查詢已存在的 ConfigMap
假設今天在不同團隊使用不同 Namespace 變成要一直指定 -n 在 kubectl 指令會很麻煩
所以比較好的方式是用一個 command 去修改目前操作的 Namespace
然而原生的 kubectl 沒有這項功能
所以只能透過一個外掛工具 kubectx/kubens 來處理
git clone https://github.com/ahmetb/kubectx
sudo cp kubectx/kube* /usr/local/bin/
當安裝成功後
就可以執行以下指令列出所有的 namespace
上面顯示黃色的就是預設的 namespace
然後透過以下指令切換 namespace
kubens $namespace_name
切換到 my-namespace 就是以下指令
切換之後結果
kubectl delete namespaces $namespace_name
要注意的是, 當刪除 namespace, 代表 namespace 下的所有佈署都會被刪除
使用 Namespace 能夠有效地分類資源
雖然官方建議當叢集少於10人的時候就不需要使用 Namespace
可是透過 Namespace 將資源分類其實對於資源管理來說其實還是優於散佈所有資源在 default Namespace
請問一下mongodb-configmap.yaml裡面, 其實在database_url還是指向到mongodb-service, 這部份可以直接在mongo-express-deployment.yaml就指定mongodb-service而不額外寫configmap嗎?
在回答你的問題之前,我想先說明 ConfigMap 的用途。
使用 ConfigMap 最主要用意,是讓在同一個 cluster 內的 deployment 都可以透過 ConfigMap 去存取這樣的 Config。分離掉 deployment 與一些 service url 的相依性。
然後回到你的問題,你是想問
mongo-express-deployment.yaml 所用到的 database_url
是否可以直接在文件內指定而不使用 ConfigMap 設定。
以我在上一篇的設定是可以的。
因為已經使用 Service 來把 mongodb 對應到 Service。
不會讓mongo-express-deployment 被 mongodb-deployment 綁定。
但是 考慮到一個情境,假設今天想要把 mongo-express 對應到的 mongodb-service 做抽換這個時候,就必須要把 mongo-express重新整個做 deployment 更換。
如果使用 ConfigMap ,會做更換的就只有 ConfigMap的設定。 在deployment 讀取到 ConfigMap 變更後,會自動修改讀取的 database_url ,而不需要做整個重建 deployment。
我個人覺得這是為何需要額外做 ConfigMap 的主要原因。